package dream_scene

import (
	"go_server/game_server/api/service/bag"
	"go_server/game_server/api/service/build"
	"go_server/game_server/constants"
	"go_server/game_server/dao/scene_info_dao"
	"go_server/game_server/dataconfig/config_manager"
	"go_server/game_server/initializer/map_data_init"
	"go_server/game_server/protocol/pb"
	"go_server/game_server/util"
	"go_server/game_server/world_manager"
	"go_server/zinx/ziface"
	"go_server/zinx/znet"
	"time"
)

type GetDreamSceneListApi struct {
	znet.BaseRouter
}

func (*GetDreamSceneListApi) Handle(request ziface.IRequest) {
	msg := &pb.GetDreamSceneListC2S{}
	if !util.PBParseRet(request, msg) {
		return
	}

	conn := request.GetConnection()
	roleId := ServiceObj.GetRoleId(request)

	curTime := time.Now().UnixMilli() // 当前毫秒时间戳

	baseSceneList := config_manager.GetStcTableLevelChapter_SheetLevelChapterList(DREAM_SCENE_EVENT_TYPE) // 关卡配置列表
	if len(baseSceneList) == 0 {
		world_manager.WorldMgrObj.SendClientErrMsg(roleId, request, pb.ErrorCodeManager_DREARM_SCENE_UNFIND, nil)
		return
	}

	gs := config_manager.GetTableGameSettingSheetGame()
	powerNum := bag.GetItemNum(roleId, DREAM_SCENE_POWER_ID) // 获取当前背包的体力值

	buildLevel := build.GetBuildLv(roleId, map_data_init.InitMapID, constants.DREAM_SCENE_BUILD_ID, constants.RESOURCE_BUILD_CFG_ID) // 获取梦境关卡建筑等级
	row := scene_info_dao.GetSceneByRoleId(roleId)

	if row == nil { // 梦境关卡初始化
		// 判断是否满足解锁等级
		firstSceneInfo, ok := baseSceneList[DREAM_SCENE_FIRST_SCENE_Id] // 第一关关卡配置信息
		if !ok {
			world_manager.WorldMgrObj.SendClientErrMsg(roleId, request, pb.ErrorCodeManager_DREARM_SCENE_UNFIND, nil)
			return
		}

		if buildLevel < firstSceneInfo.UnlockBulidLv {
			world_manager.WorldMgrObj.SendClientErrMsg(roleId, request, pb.ErrorCodeManager_DREARM_SCENE_NOT_ENOUGH_BUILDLEVEL, nil)
			return
		}

		sceneInfo := make(map[int32][]int32)
		sceneInfo[DREAM_SCENE_FIRST_SCENE_Id] = []int32{DREAM_SCENE_FIRST_SCENE_Id, 0, 0}

		scene_info_dao.CreateSceneInfo(roleId, &sceneInfo, curTime) // 激活第一关关卡

		bag.AddItemSingle(roleId, DREAM_SCENE_POWER_ID, gs.InitialStrength) // 赠送初始默认体力

		powerNum += gs.InitialStrength
	} else {
		// 如果背包体力值 < 最大上限，则恢复体力
		if powerNum < gs.StrengthMax {
			preUpdateTime := row.UpgradeTime // 上次恢复体力时间
			// 计算可以恢复的体力
			itemInfo, ok := config_manager.GetTableItemSheetItemConfig(DREAM_SCENE_POWER_ID)
			if !ok {
				world_manager.WorldMgrObj.SendClientErrMsg(roleId, request, pb.ErrorCodeManager_DREARM_SCENE_POWER_REMAIN_UNFIND, nil)
				return
			}

			intervalTime := int64(itemInfo.Par[0]) * 60 * 1000          // 恢复间隔时间 / 豪秒
			addPower := int32((curTime - preUpdateTime) / intervalTime) // 向下取整，计算本次可获得体力值

			if addPower > 0 {
				upMap := make(map[string]any)
				upMap["upgrade_time"] = preUpdateTime + int64(addPower)*intervalTime
				scene_info_dao.UpdateSceneByRoleId(roleId, &upMap) // 更新恢复体力时间

				if (powerNum + addPower) > gs.StrengthMax {
					addPower = gs.StrengthMax - powerNum
				}

				bag.AddItemSingle(roleId, DREAM_SCENE_POWER_ID, addPower) // 发送恢复的体力值
				powerNum += addPower
			}
		}
	}

	// 组装返回数据结构
	res := new(pb.GetDreamSceneListS2C)
	sceneList := make(map[int32]*pb.DreameSceneInfo)

	if row == nil || row.SceneInfo.Data() == nil { // 默认解锁第一关
		SceneBaseInfo := new(pb.DreameSceneInfo)

		SceneBaseInfo.SceneId = DREAM_SCENE_FIRST_SCENE_Id
		SceneBaseInfo.IsFirst = 0
		SceneBaseInfo.Star = 0

		sceneList[DREAM_SCENE_FIRST_SCENE_Id] = SceneBaseInfo
	} else {
		for key, value := range row.SceneInfo.Data() {
			if key != DREAM_SCENE_FIRST_SCENE_Id {
				// 判断是否满足解锁等级
				baseSceneInfo, ok := baseSceneList[key] // 获取解锁关卡的关卡配置信息
				if !ok {
					world_manager.WorldMgrObj.SendClientErrMsg(roleId, request, pb.ErrorCodeManager_DREARM_SCENE_UNFIND, nil)
					return
				}

				if buildLevel < baseSceneInfo.UnlockBulidLv { // 建筑等级未达到解锁条件,不返回给客户端
					continue
				}
			}

			SceneBaseInfo := new(pb.DreameSceneInfo)

			SceneBaseInfo.SceneId = value[0]
			SceneBaseInfo.IsFirst = value[1]
			SceneBaseInfo.Star = value[2]
			sceneList[key] = SceneBaseInfo
		}
	}

	res.SceneList = sceneList // 关卡解锁列表
	res.PowerNum = powerNum   // 获取当前背包的体力值

	conn.SendBuffPBMsg(uint32(pb.ProtocolManager_GetDreamSceneList), res)
}
